package HashMap.Nodo.Operaciones.Funciones;

import HashMap.Nodo.Categoria;
import HashMap.Nodo.Nodo;
import HashMap.Nodo.Operacion;
import HashMap.Nodo.TipoBasicoDeDatos;
import HashMap.GenerarCodigoNASM;
import HashMap.Nodo.Subclases.Escalar;
import HashMap.Pila;
import java.util.List;

public class Funcion implements Operacion {

    private final Nodo nodo;
    private final List<Nodo> parametrosFuncion;
    private Nodo nodoFinal;

    public Funcion(Nodo nodo, List<Nodo> parametrosFuncion) {
        this.nodo = nodo;
        this.parametrosFuncion = parametrosFuncion;
    }

    @Override
    public int getLongitud() {
        throw new UnsupportedOperationException("Operacion no soportada");
    }

    @Override
    public String generarCodigoNASM() {
        String llamada = "";
        for (Nodo parametro : parametrosFuncion) {
            llamada += "push " + parametro.getNombre() + "\n";
        }
        llamada += "call " + nodo.getNombre() + "\nmov [" + nodo.getNombre()
                + "], top\npop";
        return llamada;
    }

    @Override
    public Nodo generarNodo(String tokenOperacion) {
        if (nodo.getCategoria() == Categoria.FUNCION && nodo.getNumeroDeParametros() == parametrosFuncion.size()) {
            TipoBasicoDeDatos tipoBasico = nodo.getTipoBasicoDeDatos();
            GenerarCodigoNASM generador = GenerarCodigoNASM.getInstancia();
            String nombre = generador.getNombreVariableAuxiliar();
            nodoFinal = new Escalar(nombre, tipoBasico, Categoria.VARIABLE, 0, "FUNCION");
            Pila.getInstancia().addNodoALaTablaSuperior(nodoFinal);
            return nodoFinal;
        } else {
            throw new IllegalArgumentException("No se cumplen las condiciones "
                    + "para las funciones");
        }
    }
}
